﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using dpptask2.Exceptions;

namespace dpptask2.OptionClasses
{
    public abstract class optionParametrizedAttribute : optionAttribute
    {
        public override void parse(object argumentClass, CmdLineToken choiceToken, CmdLineToken parameterToken)
        {
            if (choiceToken == null)
            {
                if (this.choiceRequired)
                    throw new ParserException("Choice {0} required.", this.command);
                this.field.SetValue(argumentClass, null);
            }
            else
            {
                if (parameterToken == null)
                {
                    if (this.paramRequired)
                        throw new ParserException("Choice {0} requires parameter.", this.command);
                    else
                        this.field.SetValue(argumentClass, this.defaultValue);
                }
                else
                {
                    choiceToken.isUsed = true;
                    parameterToken.isUsed = true;
                    this.field.SetValue(argumentClass, this.createValueFromString(parameterToken.originalText));
                }
            }
        }

        public override void check()
        {
            base.check();
            checkDefaultValueDefinition();
            checkDefaultValueType();
        }

        private void checkDefaultValueDefinition()
        {
            if (this.paramRequired)
            {
                if (this.defaultValue != null)
                    throw new ParserException("Attribute {0} has defaultValue specified although parameter is required (that means defaultValue is useless).", fieldFullName());
            }
            else
            {
                if (this.defaultValue == null)
                    throw new ParserException("Attribute{0} hasn't defaultValue specified, since parameter is not required, you must specify defaultValue.", fieldFullName());
            }
        }

        public bool paramRequired = true;

        public object defaultValue { get; set; }

        public override string getUsageText(string cmd)
        {
            string paramInfo = getPureType(this.typeAccepted()).Name;

            if (!this.paramRequired)
                paramInfo = "[ " + paramInfo + " ]";

            string usageInfo = addSlashes(cmd) + " " + paramInfo;

            if (!this.choiceRequired)
                usageInfo = "[ " + usageInfo + " ]";

            return usageInfo;
        }

        public virtual object createValueFromString(string stringValue)
        {
            return null;
        }

        public void checkDefaultValueType()
        {
            if (defaultValue == null)
                return;

            Type valueType = defaultValue.GetType();
            Type expectedType = getPureType(this.typeAccepted());

            if (!valueType.Equals(expectedType))
            {
                throw new ParserException("Attribute {0} has defaultValue defined with wrong type ({1} found, {2} expected).", fieldFullName(), valueType.Name, expectedType.Name);
            }
        }
    }
}
